home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / gcc / ixemlsrc.lha / ixemul / ixnet / rcmd.c < prev    next >
C/C++ Source or Header  |  1996-03-13  |  6KB  |  221 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #if defined(LIBC_SCCS) && !defined(lint)
  35. static char sccsid[] = "@(#)rcmd.c      5.24 (Berkeley) 2/24/91";
  36. #endif /* LIBC_SCCS and not lint */
  37.  
  38. #define KERNEL
  39. #include "ixnet.h"
  40. #include <sys/param.h>
  41. #include <sys/socket.h>
  42. #include <sys/stat.h>
  43. #include <netinet/in.h>
  44. #include <arpa/inet.h>
  45. #include <signal.h>
  46. #include <fcntl.h>
  47. #include <netdb.h>
  48. #include <pwd.h>
  49. #include <errno.h>
  50. #include <stdio.h>
  51. #include <unistd.h>
  52. #include <string.h>
  53. #include "ixprotos.h"
  54.  
  55. int rcmd(char **ahost, int rport, const char *locuser, const char *remuser,
  56.     const char *cmd, int *fd2p) {
  57.     int s, timo = 1, pid;
  58.     long oldmask;
  59.     struct sockaddr_in sin, from;
  60.     char c;
  61.     int lport = IPPORT_RESERVED - 1;
  62.     struct hostent *hp;
  63.     fd_set reads;
  64.  
  65.     pid = getpid();
  66.     hp = gethostbyname(*ahost);
  67.     if (hp == 0) {
  68.     herror(*ahost);
  69.     return (-1);
  70.     }
  71.     *ahost = hp->h_name;
  72.     oldmask = sigblock(sigmask(SIGURG));
  73.     for (;;) {
  74.     s = rresvport(&lport);
  75.     if (s < 0) {
  76.         if (errno == EAGAIN)
  77.         fprintf(stderr, "socket: All ports in use\n");
  78.         else
  79.         perror("rcmd: socket");
  80.         sigsetmask(oldmask);
  81.         return (-1);
  82.     }
  83. #ifdef F_SETOWN
  84.     fcntl(s, F_SETOWN, pid);
  85. #endif
  86.     sin.sin_family = hp->h_addrtype;
  87.     bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
  88.     sin.sin_port = rport;
  89.     if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
  90.         break;
  91.     (void) close(s);
  92.     if (errno == EADDRINUSE) {
  93.         lport--;
  94.         continue;
  95.     }
  96.     if (errno == ECONNREFUSED && timo <= 16) {
  97.         sleep(timo);
  98.         timo *= 2;
  99.         continue;
  100.     }
  101.     if (hp->h_addr_list[1] != NULL) {
  102.         int oerrno = errno;
  103.  
  104.         fprintf(stderr, "connect to address %s: ",
  105.         inet_ntoa(sin.sin_addr));
  106.         errno = oerrno;
  107.         perror(0);
  108.         hp->h_addr_list++;
  109.         bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
  110.         fprintf(stderr, "Trying %s...\n", inet_ntoa(sin.sin_addr));
  111.         continue;
  112.     }
  113.     perror(hp->h_name);
  114.     sigsetmask(oldmask);
  115.     return (-1);
  116.     }
  117.     lport--;
  118.     if (fd2p == 0) {
  119.     write(s, "", 1);
  120.     lport = 0;
  121.     }
  122.     else {
  123.     char num[8];
  124.     int s2 = rresvport(&lport), s3;
  125.     int len = sizeof (from);
  126.  
  127.     if (s2 < 0)
  128.         goto bad;
  129.  
  130.     listen(s2, 1);
  131.     (void) sprintf(num, "%d", lport);
  132.     if (write(s, num, strlen(num)+1) != strlen(num)+1) {
  133.         perror("write: setting up stderr");
  134.         (void) close(s2);
  135.         goto bad;
  136.     }
  137.     FD_ZERO(&reads);
  138.     FD_SET(s, &reads);
  139.     FD_SET(s2, &reads);
  140.     errno = 0;
  141.     if (select(32, &reads, 0, 0, 0) < 1 ||
  142.         !FD_ISSET(s2, &reads)) {
  143.         if (errno != 0)
  144.         perror("select: setting up stderr");
  145.         else
  146.         fprintf(stderr, "select: protocol failure in circuit setup.\n");
  147.         (void) close(s2);
  148.         goto bad;
  149.     }
  150.     s3 = accept(s2, (struct sockaddr *)&from, &len);
  151.     (void) close(s2);
  152.     if (s3 < 0) {
  153.         perror("accept");
  154.         lport = 0;
  155.         goto bad;
  156.     }
  157.     *fd2p = s3;
  158.     from.sin_port = ntohs((u_short)from.sin_port);
  159.     if (from.sin_family != AF_INET ||
  160.         from.sin_port >= IPPORT_RESERVED ||
  161.         from.sin_port < IPPORT_RESERVED / 2) {
  162.         fprintf(stderr, "socket: protocol failure in circuit setup.\n");
  163.         goto bad2;
  164.     }
  165.     }
  166.     (void) write(s, locuser, strlen(locuser)+1);
  167.     (void) write(s, remuser, strlen(remuser)+1);
  168.     (void) write(s, cmd, strlen(cmd)+1);
  169.     if (read(s, &c, 1) != 1) {
  170.     perror(*ahost);
  171.     goto bad2;
  172.     }
  173.     if (c != 0) {
  174.     while (read(s, &c, 1) == 1) {
  175.         (void) write(2, &c, 1);
  176.         if (c == '\n')
  177.         break;
  178.     }
  179.     goto bad2;
  180.     }
  181.     sigsetmask(oldmask);
  182.     return (s);
  183. bad2:
  184.     if (lport)
  185.     (void) close(*fd2p);
  186. bad:
  187.     (void)close(s);
  188.     sigsetmask(oldmask);
  189.     return (-1);
  190. }
  191.  
  192. int
  193. rresvport(int *alport) {
  194.     struct sockaddr_in sin;
  195.     int s;
  196.  
  197.     sin.sin_family = AF_INET;
  198.     sin.sin_addr.s_addr = INADDR_ANY;
  199.     s = socket(AF_INET, SOCK_STREAM, 0);
  200.     if (s < 0)
  201.     return (-1);
  202.  
  203.     for (;;) {
  204.     sin.sin_port = htons((u_short)*alport);
  205.     if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
  206.         return (s);
  207.     if (errno != EADDRINUSE) {
  208.         (void) close(s);
  209.         return (-1);
  210.     }
  211.     (*alport)--;
  212.     if (*alport == IPPORT_RESERVED/2) {
  213.         (void) close(s);
  214.         errno = EAGAIN;        /* close */
  215.         return (-1);
  216.     }
  217.     }
  218. }
  219.  
  220.  
  221.